package secondary

import "fmt"

/*
	在一个数组 nums 中除一个数字只出现一次之外，其他数字都出现了三次。请找出那个只出现一次的数字。

	示例 1：

	输入：nums = [3,4,3,3]
	输出：4
	示例 2：

	输入：nums = [9,1,7,9,7,9,7]
	输出：1

	限制：

	1 <= nums.length <= 10000
	1 <= nums[i] < 2^31

	来源：力扣（LeetCode）
	链接：https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof
	著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
*/
/*
	根据题意、所有出现了3次的数字、其二进制位上、为1的次数出现了3次、所以先计算出所有元素二进制位上的1的总和、再对3取余、得到的二进制进行还原
	即可得到只出现一次的数字
*/
func SingleNumber(nums []int) int {
	return singleNumber1(nums)
}
func singleNumber(nums []int) int {
	ret := make([]int, 32)
	for i := 0; i < len(nums); i++ {
		mask := 1
		for k := 31; k >= 0; k-- {
			if mask&nums[i] == mask {
				ret[k]++
				ret[k] = ret[k] % 3
			}
			mask <<= 1
		}
	}
	fmt.Println(ret)

	// 二进制数组转整数
	res := 0
	mask := 1
	for i := 31; i >= 0; i-- {
		res += (mask * ret[i])
		mask <<= 1
	}
	return res
}
func singleNumber1(nums []int) int {
	ret := make([]int, 32)
	for _, num := range nums {
		mask := 1
		for i := 31; i >= 0; i-- {
			if mask&num == mask {
				ret[i]++
				ret[i] %= 3
			}
			mask <<= 1
		}
	}
	fmt.Println(ret)
	res := 0
	m := 1
	for i := 31; i >= 0; i-- {
		res += (m * ret[i])
		m <<= 1
	}
	return res
}
